//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2005-2007
//
// Object properties dialog - 'Waypoint' page.
//

# include "StdAfx.h"
# include "Resource.h"
# include "RgnProperties.h"
# include "PropertyPages.h"
# include "Map.h"
# include "Types.h"
# include "Rename.h"
# include "SetComment.h"
# include "ShowRgnOnMap.h"
# include "PrintUnits.h"
# include "Static.h"
# include "Button.h"
# include "fast_floor.h"
# include "Settings.h"
# include "Globals.h"

void CWptPage::_FillType () {
	const type_desc_t * const pTD = g_map.pTypeSet->GetTypeDesc (m_rgn.ushType, m_rgn.Kind);
	assert (m_rgn.Kind < rkMax);
	SetDlgItemTextF (IDC_TYPE, "%s (0x%x, %s)", pTD ? pTD->strTypeName : GetStr (IDS_UNKNOWN), m_rgn.ushType, GetStr (IDS_WAYPOINT));
}

static const char * g_strShowItems [] = {
	"Symbol and Name",
	"Symbol and Description",
	"Symbol Only",
	"Hide",
};

const size_t c_cShowItems = sizeof (g_strShowItems)/sizeof (g_strShowItems [0]);

bool CWptPage::OnInit (HWND _hwndFocus) {
	// Type.
	_FillType ();

	// Label.
	SetDlgItemText (IDC_LABEL,   m_rgn.strLabel.c_str ());

	// Description.
	SetDlgItemText (IDC_COMMENT, m_rgn.strComment.c_str ());

	// Position.
	char strLat [32] = "";
	char strLon [32] = "";
	if (m_rgn.origins.size () > 0) {
		PrintLat (strLat, m_rgn.origins [0].point.y);
		PrintLon (strLon, m_rgn.origins [0].point.x);
	}
	SetDlgItemText (IDC_LATITUDE,  strLat);
	SetDlgItemText (IDC_LONGITUDE, strLon);

	waypoint_info_t * const pWptExtra = m_rgn.pExtra ? m_rgn.pExtra->wtr.wpt () : NULL;

	// Altitude.
	if (pWptExtra && (pWptExtra->wFlags & waypoint_info_t::defAltitude) != 0) {
		char strAltitude [32];
		char strAltitudeUnit [16];
		PrintElevation (strAltitude, strAltitudeUnit, pWptExtra->fAltitude, unMeters, false);

		SetDlgItemText (IDC_ALTITUDE,      strAltitude);
		SetDlgItemText (IDC_ALTITUDE_UNIT, strAltitudeUnit);
	} else
		SetDlgItemText (IDC_ALTITUDE_UNIT, "");

	// Time.
	if (pWptExtra && (pWptExtra->wFlags & waypoint_info_t::defTime) != 0) {
		// Get time zone bias + daylight saving time bias.
		TIME_ZONE_INFORMATION tzi;
		if (::GetTimeZoneInformation (& tzi) == TIME_ZONE_ID_DAYLIGHT)
			tzi.Bias += tzi.DaylightBias;

		SYSTEMTIME st;
		::VariantTimeToSystemTime (pWptExtra->dtTime - float (tzi.Bias)/(24*60), & st);

		char strDate [32];
		if (! ::GetDateFormat (LOCALE_USER_DEFAULT, DATE_LONGDATE, & st, NULL, strDate, sizeof (strDate)/sizeof (strDate [0])))
			strDate [0] = '\0';
		char strTime [32];
		if (! ::GetTimeFormat (LOCALE_USER_DEFAULT, 0, & st, NULL, strTime, sizeof (strTime)/sizeof (strTime [0])))
			strTime [0] = '\0';

		SetDlgItemTextF (IDC_TIME, "%s %s", strDate, strTime);
	}

	// Depth.
	if (pWptExtra && (pWptExtra->wFlags & waypoint_info_t::defDepth) != 0) {
		char strDepth [32];
		char strDepthUnits [16];
		PrintDepth (strDepth, strDepthUnits, pWptExtra->fDepth);

		SetDlgItemText (IDC_DEPTH,      strDepth);
		SetDlgItemText (IDC_DEPTH_UNIT, strDepthUnits);
	} else
		SetDlgItemText (IDC_DEPTH_UNIT, "");

	// Temperature.
	if (pWptExtra && (pWptExtra->wFlags & waypoint_info_t::defTemperature) != 0) {
		char strTemperature [32];
		char strTemperatureUnits [16];
		PrintTemperature (strTemperature, strTemperatureUnits, pWptExtra->fTemperature);

		SetDlgItemText (IDC_TEMPERATURE,      strTemperature);
		SetDlgItemText (IDC_TEMPERATURE_UNIT, strTemperatureUnits);
	} else
		SetDlgItemText (IDC_TEMPERATURE_UNIT, "");

	// Proximity.
	if (pWptExtra && (pWptExtra->wFlags & waypoint_info_t::defProximity) != 0) {
		char strProximity [32];
		char strProximityUnits [16];
		PrintDistance (strProximity, strProximityUnits, pWptExtra->fProximity);

		SetDlgItemText (IDC_PROXIMITY,      strProximity);
		SetDlgItemText (IDC_PROXIMITY_UNIT, strProximityUnits);
	} else
		SetDlgItemText (IDC_PROXIMITY_UNIT, "");

	// Show.
	const HWND hShow = GetDlgItem (IDC_SHOW);
	if (pWptExtra) {
		for (size_t cShow = 0; cShow < c_cShowItems; ++ cShow) {
			::SendMessage (hShow, CB_INSERTSTRING, cShow, (LPARAM) g_strShowItems [cShow]);
			::SendMessage (hShow, CB_SETITEMDATA,  cShow, cShow);
			if (size_t (pWptExtra->GetShow ()) == cShow)
				::SendMessage (hShow, CB_SETCURSEL, cShow, 0);
		}
	}
	::EnableWindow (hShow, FALSE);

	// Link.
	if (pWptExtra) {
		if (pWptExtra->strURL.empty ())
			EnableDlgItem (IDC_LINK_BROWSE, false);
		else
			SetDlgItemText (IDC_LINK, pWptExtra->strURL.c_str ());
	}
	SetButtonIcon (m_hWnd, IDC_LINK_BROWSE, IDI_BROWSE);

	return true;
}

void CWptPage::OnCommand (WORD _wCmd, WORD _wNotifyCode, HWND _hwndCtl) {
	switch (_wCmd) {
		case IDC_LINK_BROWSE: {
			char strWebLink [256];
			GetDlgItemText (IDC_LINK, strWebLink, sizeof (strWebLink)/sizeof (strWebLink [0]));
			::ShellExecute (m_hWnd, NULL, strWebLink, NULL, NULL, SW_SHOWNORMAL);
			break;
		}

		case IDC_SHOW_ON_MAP:
			ShowRgnOnMap (m_rgn);
			break;

		case IDC_LABEL:
		case IDC_COMMENT:
		case IDC_LINK:
		case IDC_ALTITUDE:
		case IDC_DEPTH:
		case IDC_TEMPERATURE:
		case IDC_PROXIMITY:
			if (_wNotifyCode == EN_UPDATE)
				PropSheetChanged ();
			break;
	}
}

void CWptPage::OnApply (const PSHNOTIFY *) {
	// Label.
	const HWND hLabel = GetDlgItem (IDC_LABEL);
	const size_t cLabelLen = ::GetWindowTextLength (hLabel);
	char * const strLabel = reinterpret_cast<char *> (alloca (cLabelLen + 1));
	::GetWindowText (hLabel, strLabel, cLabelLen + 1);
	if (! (m_rgn.strLabel == strLabel))
		RenameObject (m_rgn, strLabel);

	// Comment.
	const HWND hComment = GetDlgItem (IDC_COMMENT);
	const size_t cCommentLen = ::GetWindowTextLength (hComment);
	char * const strComment = reinterpret_cast<char *> (alloca (cCommentLen + 1));
	::GetWindowText (hComment, strComment, cCommentLen + 1);
	if (! (m_rgn.strComment == strComment))
		SetComment (m_rgn, strComment);

	// Type.
//	if (m_rgn.ushType != g_ushType)
//		ChangeType (m_rgn, g_ushType);

	RefreshRequired ();
}
